package edu.szcu.vitaguard.dao;

import edu.szcu.vitaguard.entity.Prescription;
import org.apache.ibatis.annotations.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 处方DAO接口
 */
@Mapper
public interface PrescriptionDao {
    
    /**
     * 插入处方
     * @param prescription 处方对象
     * @return 影响的行数
     */
    @Insert("INSERT INTO prescription(visit_id, patient_id, doctor_id, prescription_date, " +
            "diagnosis, instructions, status, create_time, update_time) " +
            "VALUES(#{visitId}, #{patientId}, #{doctorId}, #{prescriptionDate}, " +
            "#{diagnosis}, #{instructions}, #{status}, #{createTime}, #{updateTime})")
    @Options(useGeneratedKeys = true, keyProperty = "prescriptionId")
    int insert(Prescription prescription);
    
    /**
     * 根据ID查询处方
     * @param prescriptionId 处方ID
     * @return 处方对象
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.prescription_id = #{prescriptionId}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    Prescription selectById(Integer prescriptionId);
    
    /**
     * 查询所有处方
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectAll();
    
    /**
     * 根据患者ID查询处方
     * @param patientId 患者ID
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.patient_id = #{patientId}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectByPatientId(Integer patientId);
    
    /**
     * 根据医生ID查询处方
     * @param doctorId 医生ID
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.doctor_id = #{doctorId}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectByDoctorId(Integer doctorId);
    
    /**
     * 根据就诊记录ID查询处方
     * @param visitId 就诊记录ID
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.visit_id = #{visitId}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectByVisitId(Integer visitId);
    
    /**
     * 根据日期范围查询处方
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.prescription_date BETWEEN #{startDate} AND #{endDate}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectByDateRange(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);
    
    /**
     * 根据状态查询处方
     * @param status 状态
     * @return 处方列表
     */
    @Select("SELECT p.*, pt.patient_name, pt.gender, pt.birth, pt.phone, pt.id_card, " +
            "d.doctor_name, d.title, d.introduction, d.status as doctor_status, " +
            "v.visit_date, v.diagnosis as visit_diagnosis, v.treatment_plan " +
            "FROM prescription p " +
            "LEFT JOIN patient pt ON p.patient_id = pt.patient_id " +
            "LEFT JOIN doctor d ON p.doctor_id = d.doctor_id " +
            "LEFT JOIN visit_record v ON p.visit_id = v.visit_id " +
            "WHERE p.status = #{status}")
    @Results({
        @Result(property = "prescriptionId", column = "prescription_id"),
        @Result(property = "visitId", column = "visit_id"),
        @Result(property = "patientId", column = "patient_id"),
        @Result(property = "doctorId", column = "doctor_id"),
        @Result(property = "prescriptionDate", column = "prescription_date"),
        @Result(property = "diagnosis", column = "diagnosis"),
        @Result(property = "instructions", column = "instructions"),
        @Result(property = "status", column = "status"),
        @Result(property = "patient", column = "patient_id", javaType = edu.szcu.vitaguard.entity.Patient.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.PatientDao.selectById")),
        @Result(property = "doctor", column = "doctor_id", javaType = edu.szcu.vitaguard.entity.Doctor.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.DoctorDao.selectById")),
        @Result(property = "visitRecord", column = "visit_id", javaType = edu.szcu.vitaguard.entity.VisitRecord.class, 
                one = @One(select = "edu.szcu.vitaguard.dao.VisitRecordDao.selectById"))
    })
    List<Prescription> selectByStatus(Integer status);
    
    /**
     * 更新处方
     * @param prescription 处方对象
     * @return 影响的行数
     */
    @Update("UPDATE prescription SET visit_id = #{visitId}, patient_id = #{patientId}, " +
            "doctor_id = #{doctorId}, prescription_date = #{prescriptionDate}, diagnosis = #{diagnosis}, " +
            "instructions = #{instructions}, status = #{status}, update_time = #{updateTime} " +
            "WHERE prescription_id = #{prescriptionId}")
    int update(Prescription prescription);
    
    /**
     * 删除处方
     * @param prescriptionId 处方ID
     * @return 影响的行数
     */
    @Delete("DELETE FROM prescription WHERE prescription_id = #{prescriptionId}")
    int deleteById(Integer prescriptionId);
    
    /**
     * 根据查询条件统计处方数量
     * @param query 查询条件
     * @return 处方数量
     */
    int selectCountByQuery(edu.szcu.vitaguard.vo.PrescriptionQuery query);
    
    /**
     * 分页查询处方
     * @param query 查询条件
     * @return 处方列表
     */
    List<Prescription> selectByPage(edu.szcu.vitaguard.vo.PrescriptionQuery query);
    
    /**
     * 更新处方状态和发药时间
     * @param prescriptionId 处方ID
     * @param status 状态
     * @param dispenseTime 发药时间
     * @return 影响的行数
     */
    @Update("UPDATE prescription SET status = #{status}, dispense_time = #{dispenseTime} WHERE prescription_id = #{prescriptionId}")
    int updateStatusAndDispenseTime(@Param("prescriptionId") Integer prescriptionId, 
                                  @Param("status") String status, 
                                  @Param("dispenseTime") LocalDateTime dispenseTime);
    
    /**
     * 更新处方状态和退药时间
     * @param prescriptionId 处方ID
     * @param status 状态
     * @param returnTime 退药时间
     * @return 影响的行数
     */
    @Update("UPDATE prescription SET status = #{status}, return_time = #{returnTime} WHERE prescription_id = #{prescriptionId}")
    int updateStatusAndReturnTime(@Param("prescriptionId") Integer prescriptionId, 
                                @Param("status") String status, 
                                @Param("returnTime") LocalDateTime returnTime);
}